package com.xiaogao.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaogao.autofill.annotation.FillUserInfo;
import com.xiaogao.common.entity.PageData;
import com.xiaogao.common.exception.BusinessException;
import com.xiaogao.common.utils.BeanListUtils;
import com.xiaogao.sys.mapper.SysDictDataMapper;
import com.xiaogao.sys.mapper.SysDictTypeMapper;
import com.xiaogao.sys.model.SysDictData;
import com.xiaogao.sys.model.SysDictType;
import com.xiaogao.sys.request.dict.type.AddParam;
import com.xiaogao.sys.request.dict.type.QueryParam;
import com.xiaogao.sys.request.dict.type.UpdateParam;
import com.xiaogao.sys.response.SysDictTypeResponse;
import com.xiaogao.sys.service.SysDictTypeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@RequiredArgsConstructor
@Service
@Slf4j
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements SysDictTypeService {
    private final SysDictTypeMapper sysDictTypeMapper;
    private final SysDictDataMapper sysDictDataMapper;

    @Override
    public void delete(List<String> ids) {
        if (!CollectionUtils.isEmpty(ids)) {
            // 批量删除
            LambdaQueryWrapper<SysDictType> sysDictTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sysDictTypeLambdaQueryWrapper.in(SysDictType::getId,ids);
            sysDictTypeLambdaQueryWrapper.select(SysDictType::getType);
            List<String> types = sysDictTypeMapper.selectObjs(sysDictTypeLambdaQueryWrapper);
            // types
            if (!CollectionUtils.isEmpty(types)) {
                LambdaQueryWrapper<SysDictData> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(SysDictData::getType, types); // mybatis : where type in ('aaa','bbb')
                queryWrapper.select(SysDictData::getType);
                // 这些types在数据库中都存在字典数据
                List<String> sysDictDataTypes = sysDictDataMapper.selectObjs(queryWrapper).stream()
                        .map(obj -> (String) obj)
                        .distinct()
                        .toList();
                if (!CollectionUtils.isEmpty(sysDictDataTypes)) {
                    throw new BusinessException(500, String.format("下列字典类型都存在字典数据，不能删除这些字典类型！字典类型为：%s", String.join(",", sysDictDataTypes)));
                }
                // 批量删除
                sysDictTypeMapper.deleteByIds(ids);
            }
        }
    }

    @Override
    public void add(AddParam addParam) {
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotEmpty(addParam.getType()), SysDictType::getType, addParam.getType());
        SysDictType dbSysDictType = sysDictTypeMapper.selectOne(queryWrapper);
        if (dbSysDictType == null) {
            SysDictType sysDictType = new SysDictType();
            BeanUtils.copyProperties(addParam, sysDictType);
            sysDictTypeMapper.insert(sysDictType);
        }
    }

    @Override
    public void update(UpdateParam updateParam) {
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotEmpty(updateParam.getType()), SysDictType::getType, updateParam.getType());
        SysDictType dbSysDictType = sysDictTypeMapper.selectOne(queryWrapper);
        if (dbSysDictType == null) {
            throw new BusinessException(500, "数据非法！");
        }
        BeanUtils.copyProperties(updateParam, dbSysDictType);
        sysDictTypeMapper.updateById(dbSysDictType);
    }

    @FillUserInfo
    @Override
    public PageData<SysDictTypeResponse> querySeletive(Integer pageNum, Integer pageSize, QueryParam queryParam) {
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotEmpty(queryParam.getType()), SysDictType::getType, queryParam.getType());
        queryWrapper.like(StringUtils.isNotEmpty(queryParam.getName()), SysDictType::getName, queryParam.getName());
        Long count = sysDictTypeMapper.selectCount(queryWrapper);
        if (count == 0L) {
            return new PageData<>(new ArrayList<>(), 0L);
        }
        queryWrapper.orderByDesc(SysDictType::getCreateTime);
        Integer offset = (pageNum - 1) * pageSize;
        queryWrapper.last(String.format("limit %d,%d", offset, pageSize));
        List<SysDictType> list = sysDictTypeMapper.selectList(queryWrapper);
        List<SysDictTypeResponse> sysDictTypeResponses = BeanListUtils.copyList(list, SysDictTypeResponse.class);
        return new PageData<>(sysDictTypeResponses, count);
    }
}
